//
// Created by Dell on 2020-12-25.
//

#include "cpt.h"

int find_class(JNIEnv *env, const char *name, jclass *clazz_out) {
    jclass clazz = env->FindClass(name);
    if (clazz == nullptr) {
        printf("Can't find %s\n", name);
        return -1;
    }
    *clazz_out = (jclass) env->NewGlobalRef(clazz); // 这里必须新建一个全局的引用
    return 0;
}

int get_field(JNIEnv *env, jclass *clazz, const char *name, const char *sig, jfieldID *field_out) {
    jfieldID filed = env->GetFieldID(*clazz, name, sig);
    if (filed == nullptr) {
        printf("Can't find. filed name: %s, sig: %s\n", name, sig);
        return -1;
    }
    *field_out = filed;
    return 0;
}

void register_sub_policy_class(JNIEnv *env) {
    int ret = find_class(env, "com/teradata/jni/SubPolicy", &m_jni_sub_policy_block.clazz);
    if (ret != 0) {
        printf("register_sub_policy_class failed\n");
        return;
    }
    jclass clazz = m_jni_sub_policy_block.clazz;
    // 构造方法
    m_jni_sub_policy_block.constructor = env->GetMethodID(clazz, "<init>", "()V");
    // 成员
    get_field(env, &clazz, "position", "I", &m_jni_sub_policy_block.position);
    get_field(env, &clazz, "length", "I", &m_jni_sub_policy_block.length);
}

void register_policy_class(JNIEnv *env) {
    int ret = find_class(env, "com/teradata/jni/Policy", &m_jni_policy_block.clazz);
    if (ret != 0) {
        printf("register_policy_class failed\n");
        return;
    }
    jclass clazz = m_jni_policy_block.clazz;
    // 构造方法
    m_jni_policy_block.constructor = env->GetMethodID(clazz, "<init>", "()V");
    // 成员
    get_field(env, &clazz, "sub_policy_num", "I", &m_jni_policy_block.sub_policy_num);
    get_field(env, &clazz, "sub_policy", "[Lcom/teradata/jni/SubPolicy;", &m_jni_policy_block.sub_policy);
}

void register_classes(JNIEnv *env) {
    register_sub_policy_class(env);
    register_policy_class(env);
}